/**
 * 上传图片组件
 * @param {String} domId
 * @param {Object} config
 */
export const $UploadImg = function(domId, config) {
  // debugger
  this.dom = document.querySelector(domId)
  if (config.domCls && config.domCls.length > 0) {
    // debugger
    config.domCls.forEach(cls => {
      this.dom.classList.add(cls)
    })
  }

  // const uploadImg = {
  //     // dom: document.querySelector('#uploadDom'),
  //     picDom: document.querySelector('#uploadDom .pic-box'),
  //     addBtnDom: document.querySelector('#uploadDom .add-box'),
  //     imgsUrl: '',
  //     mime: '',
  //     viewNum: [],
  //     list: []
  // }

  this.conf = {
    imgsUrl: '',
    mime: '',
    viewNum: 0,
    list: [],
    clickEvents: null // 父级委托点击事件

    // limitNum: 100, // 限制上传数量
    // isAdd: true, // 是否允许新增
    // isDelOrigin: true, // 原图能否删除 默认能删除true
    // isDelNew: true, // 新添加图能否删除 默认能删除true
    // originList: [], // 原图数组
    // addList: [], // 新增图片数组
    // allPicList: [], // 原图数组 + 新增图片数组
  }

  if (this.getType(config) === 'object') {
    for (let k in this.conf) {
      if (k && config.hasOwnProperty(k)) {
        this.conf[k] = config[k]
      }
    }
  }

  this.init()
  this.initEvent()
}

$UploadImg.prototype = {
  getData() {
    return this.conf.list
  },
  /**
   * dom元素初始化
   */
  init() {
    this.picDom = document.createElement('div')
    this.picDom.classList.add(
      'pic-box',
      'wrap',
      'clearfix',
      'pic-box',
      'no-pic'
    )

    this.addBtnDom = document.createElement('div')
    this.addBtnDom.classList.add('add-box', 'pic-grid-item')

    this.addIcon = document.createElement('i')
    this.addIcon.classList.add(
      'iconfont',
      'has-pic-type',
      'icon-xinzeng',
      'add-btn',
      'info-font-color'
    )

    this.cameraIcon = document.createElement('i')
    this.cameraIcon.classList.add(
      'iconfont',
      'no-pic-type',
      'camera-icon',
      'icon-camera-icon'
    )
    const brDom = document.createElement('br')

    const textDom = document.createElement('span')
    textDom.classList.add('txt', 'no-pic-type', 'upload-tip-txt')
    textDom.innerText = '上传图片'

    this.inputForm = document.createElement('input')
    this.inputForm.classList.add('camera-input', 'file-input')
    // this.inputForm.id = 'cameraDom';
    this.inputForm.type = 'file'
    this.inputForm.accept = 'image/*'
    this.inputForm.capture = 'camera'
    this.inputForm.multiple = 'multiple'

    this.addBtnDom.appendChild(this.addIcon)
    this.addBtnDom.appendChild(this.cameraIcon)
    this.addBtnDom.appendChild(brDom)
    this.addBtnDom.appendChild(textDom)
    this.addBtnDom.appendChild(this.inputForm)

    this.picDom.appendChild(this.addBtnDom)
    this.dom.appendChild(this.picDom)
  },
  initEvent() {
    const _this = this
    // 表单值变更触发
    this.inputForm.addEventListener('change', function (e) {
      // debugger
      _this.fileChange(e)
    })

    // 图片上传组件 点击事件 绑定
    this.dom.addEventListener('tap', function (e) {
      const target = e.target
      // console.log('classList', target.classList)
      if (!target) return

      // 删除图片
      if (target.classList.contains('close-icon')) {
        const id = target.dataset.id;

        for (let i = 0; i < _this.conf.list.length; i++) {
          let obj = _this.conf.list[i]

          if (obj.id === id) {
            const imgDomArr = _this.dom.querySelectorAll('.pic-grid-item')
            _this.picDom.removeChild(imgDomArr[i])
            _this.conf.list.splice(i, 1)
            _this.conf.viewNum--
            if (_this.conf.list.length <= 0) {
              // debugger
              _this.picDom.classList.remove('has-pic')
              _this.picDom.classList.add('no-pic')
            }
            break
          }
        }
      }

      // 委托事件回调
      if (_this.conf.clickEvents) {
        _this.conf.clickEvents(e)
      }
    })
  },
  // 创建 新增的图片 dom
  createImgDom(arr) {
    const _this = this
    // debugger
    // console.log('arr:', arr)
    if (arr.length > 0) {
      // 有图片
      for (let obj of arr) {
        // console.log('obj:', obj)
        const span = document.createElement('span')
        const img = document.createElement('img')
        const closeIcon = document.createElement('i')
        closeIcon.innerHTML = 'x'
        closeIcon.dataset.id = obj.id
        span.classList.add('pic-grid-item')
        img.classList.add('pic-item')
        img.setAttribute('data-preview-src', obj.imgUrl)
        img.setAttribute('data-preview-group', '1')
        // img.dataset['preview-src'] = '';
        // img.dataset['preview-group'] = this.conf.viewNum.length;

        closeIcon.classList.add('icon', 'close-icon')
        img.src = obj.imgUrl
        span.appendChild(closeIcon)
        span.appendChild(img)
        // span.style.backgroundImage = `url(${obj.imgUrl})`;
        _this.picDom.insertBefore(span, _this.addBtnDom)
        _this.conf.viewNum++
      }
      _this.picDom.classList.remove('no-pic')
      _this.picDom.classList.add('has-pic')
    } else {
      // 没有图片
      // debugger
      _this.picDom.classList.remove('has-pic')
      _this.picDom.classList.add('no-pic')
    }
  },
  /**
   * database64文件格式转换为2进制
   * @param  {[String]} data dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字，我们只需要逗号之后的就行了
   * @param  {[String]} mime [description]
   * @return {[blob]}      [description]
   */
  data2blob(data, mime) {
    data = data.split(',')[1]

    // window.btoa 和 window.atob
    // window.btoa() 编码一个可能在传输过程中出现问题的数据，并且在接受数据之后，使用 atob() 方法再将数据解码
    // window.atob() 对经过 base-64 编码的字符串进行 解码
    // 兼容性IE10以上和其他浏览器都支持，还是相对不错的，要是移动端都支持。
    // 针对IE浏览器无法兼容，可以引入polyfill库，或者直接不进行 编码 。
    // window.btoa('这是中文')，中文直接编码是会抛出异常的
    data = window.atob(data)

    // Uint8Array
    // 数组类型表示一个8位无符号整型数组，创建时内容被初始化为0。创建完后，可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
    // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array#语法格式
    var ia = new Uint8Array(data.length)

    for (var i = 0; i < data.length; i++) {
      ia[i] = data.charCodeAt(i)
    }
    // canvas.toDataURL 返回的默认格式就是 image/png
    return new Blob([ia], {
      type: mime
    })
  },
  /**
   * input chanage 触发事件
   */
  fileChange(e) {
    const files = e.target.files || e.dataTransfer.files
    // console.log('********,files', files)
    if (files.length <= 0) {
      return
    }
    this.autoSeria(files, 0)
  },
  /**
   * 序列化文件 自我调用
   * @param {Array} arr 文件数组
   * @param {String|Number} index 数组索引
   */
  autoSeria(arr, index) {
    const _this = this
    if (index <= arr.length) {
      const fileObj = arr[index]
      index++
      this.setSourceImg(fileObj).then(() => {
        // console.log('eee:', eee)
        const fileBlob = _this.data2blob(_this.conf.imgsUrl, _this.conf.mime)
        const res = {
          name: fileObj.name,
          imgUrl: _this.conf.imgsUrl,
          file: fileBlob,
          id: Math.random()
            .toString()
            .replace('.', '1')
        }
        _this.createImgDom([res])
        _this.conf.list.push(res)
        // console.log('res:', res)

        if (index < arr.length) {
          // debugger
          this.autoSeria(arr, index)
        }

        // return res;
        // this.$emit('updateImgData', res)
      })
    }
  },
  /**
   * 二进制流的生成
   */
  setSourceImg(file) {
    const _this = this
    return new Promise((resolve, reject) => {
      const fr = new FileReader()
      fr.onload = function (e) {
        _this.conf.imgsUrl = fr.result
        _this.conf.mime = file.type
        resolve(fr.result)
      }
      fr.onerror = function () {
        reject()
      }
      fr.readAsDataURL(file)
    })
  },

  /**
   * 获取对象属性类型
   * @param e
   * @returns {string}
   */
  getType(e) {
    if (e == null) {
      return ''
    }
    if (e.constructor === Array) {
      return 'array'
    } else if (e.constructor === Object) {
      return 'object'
    } else if (e.constructor === String) {
      return 'string'
    } else if (e.constructor === Number) {
      return 'number'
    } else if (e.constructor === Boolean) {
      return 'boolean'
    }
    return ''
  }
}
